﻿#region File Description
/****************************************************************************
*                                                                           *
* Game Manager.                                                             *
*                                                                           *
* Copyright (c) Ionescu Marius. All rights reserved(2013).                  *
*                                                                           *
****************************************************************************/
#endregion
namespace Silverlight3D
{
    using System;
    using System.Collections.Generic;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;

    /// <summary>
    /// A VectorRect where the sides can be shaded.
    /// </summary>
    public class ShadedVectorRect : VectorRect
    {       
        public ShadedVectorRect()
            : base()
        {
        }        

        public override void Draw(Projector projector, Canvas canvas, IShader shader, Vector rotationCenter)
        {
            this.Draw(projector, canvas, shader, null, rotationCenter);
        }

        public override void Draw(Projector projector, Canvas canvas, IShader shader, Vector viewPosition, Vector rotationCenter)
        {
            base.Draw(projector, canvas, shader, viewPosition, rotationCenter);

            if (!this.IsBackFacing(projector, rotationCenter))
            {
                var vectorPolygon = new VectorPolygon();
                vectorPolygon.AddVector(this.Vector0);
                vectorPolygon.AddVector(this.Vector1);
                vectorPolygon.AddVector(this.Vector2);
                vectorPolygon.AddVector(this.Vector3);

                vectorPolygon.BrightnessFactor = 0.4;
                vectorPolygon.HideIfBackFacing = false;  // we've already checked this

                var shading = vectorPolygon.Shading(projector, rotationCenter);

                vectorPolygon.FillColor = Color.FromArgb((byte)(255 - (shading * 255)), 0, 0, 0);

                vectorPolygon.Draw(projector, canvas, shader, viewPosition, rotationCenter);
            }
        }

        public override VectorObject Clone()
        {
            var result = new ShadedVectorRect();

            result.Vector0 = this.Vector0;
            result.Vector1 = this.Vector1;
            result.Vector3 = this.Vector3;

            result.FillColor = this.FillColor;
            result.Content = this.Content;
            result.ContentSize = this.ContentSize;

            return result;
        }

        /// <summary>
        /// Returns true if the VectorRect is back facing and therefore doesn't need to be rendered.
        /// </summary>
        private bool IsBackFacing(Projector projector, Vector rotationCenter)
        {
            if (rotationCenter == null)
            {
                rotationCenter = new Vector(0, 0, 0);
            }

            var rotatedVectorRect = projector.Rotate(this, rotationCenter);

            var edge1 = rotatedVectorRect.Vector0 - rotatedVectorRect.Vector1;
            var edge2 = rotatedVectorRect.Vector0 - rotatedVectorRect.Vector3;

            var normal = VectorHelper.CrossProduct(edge1, edge2);

            var vectorRectToViewPosition = projector.ViewPosition.AddZ(-projector.ScreenDistance) - rotatedVectorRect.Center();

            var dotProduct = VectorHelper.DotProduct(normal, vectorRectToViewPosition);

            return dotProduct <= 0;
        }
    }
}